package cloud.xcan.angus.core.tester.application.query.config.impl;


import static cloud.xcan.angus.core.tester.application.converter.SettingUserConverter.assembleProxyConfig;

import cloud.xcan.angus.core.biz.Biz;
import cloud.xcan.angus.core.biz.BizTemplate;
import cloud.xcan.angus.core.tester.application.query.config.SettingTenantQuery;
import cloud.xcan.angus.core.tester.application.query.config.SettingUserQuery;
import cloud.xcan.angus.core.tester.domain.config.tenant.TenantSetting;
import cloud.xcan.angus.core.tester.domain.config.user.UserSetting;
import cloud.xcan.angus.core.tester.domain.config.user.UserSettingRepo;
import cloud.xcan.angus.core.tester.domain.config.user.apiproxy.UserApiProxy;
import cloud.xcan.angus.remote.message.http.ResourceNotFound;
import cloud.xcan.angus.spec.experimental.Assert;
import jakarta.annotation.Resource;
import java.util.Objects;

/**
 * <p>
 * Implementation of user setting query operations.
 * </p>
 * <p>
 * Manages user setting retrieval, validation, and proxy configuration. Provides comprehensive user
 * setting querying with tenant setting support.
 * </p>
 * <p>
 * Supports user setting detail retrieval, proxy configuration assembly, and tenant setting
 * integration for comprehensive user configuration administration.
 * </p>
 */
@Biz
public class SettingUserQueryImpl implements SettingUserQuery {

  @Resource
  private UserSettingRepo settingUserRepo;
  @Resource
  private SettingTenantQuery settingTenantQuery;

  /**
   * <p>
   * Retrieves proxy configuration by tenant ID.
   * </p>
   * <p>
   * Fetches tenant setting and assembles proxy configuration. Validates tenant setting existence
   * before proxy assembly.
   * </p>
   */
  @Override
  public UserApiProxy findProxyByTenantId(Long optTenantId) {
    return new BizTemplate<UserApiProxy>() {

      @Override
      protected UserApiProxy process() {
        TenantSetting tenantSetting = settingTenantQuery.findAndInit(optTenantId);
        Assert.assertNotNull(tenantSetting, "Tenant setting not found");
        return assembleProxyConfig(tenantSetting);
      }
    }.execute();
  }

  /**
   * <p>
   * Retrieves user setting by user ID with validation.
   * </p>
   * <p>
   * Returns user setting with existence validation. Throws ResourceNotFound if user setting does
   * not exist.
   * </p>
   */
  @Override
  public UserSetting find(Long userId) {
    return settingUserRepo.findById(userId).orElseThrow(
        () -> ResourceNotFound.of(userId, "UserSetting"));
  }

  /**
   * <p>
   * Retrieves user setting by user ID without validation.
   * </p>
   * <p>
   * Returns user setting without existence validation. Returns null if user setting does not
   * exist.
   * </p>
   */
  @Override
  public UserSetting find0(Long userId) {
    UserSetting settingUser = settingUserRepo.findById(userId).orElse(null);
    return Objects.isNull(settingUser) ? null : settingUser;
  }
}
